package cn.edu.csust.coursecard.service.impl;

import cn.edu.csust.coursecard.dao.dto.TaskRequest;
import cn.edu.csust.coursecard.dao.dto.TaskResult;
import cn.edu.csust.coursecard.service.IClusterTaskService;
import cn.edu.csust.coursecard.websocket.WebSocket;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;

@Service
public class ClusterTaskServiceImpl implements IClusterTaskService {
    @Resource
    private WebSocket clusterWebSocket;


    @Override
    public int getConnCount() {
        return clusterWebSocket.getConnCount();
    }

    @Override
    public String newTask(TaskRequest request) throws Throwable {
        int connCount = clusterWebSocket.getConnCount();
        double taskIdRaw = Math.random();
        double unit = 1.0 / connCount;
        int targetNum = (int) (taskIdRaw / unit);
        String nodeId = WebSocket.nodeIds.get(targetNum);

        // taskId直接转String用于任务有可能带来难以意料的问题（位数问题，科学计数法，序列长短不一等问题）
        // 采用md5作为实际taskId，原double taskId仅用于分发任务
        String taskId = DigestUtils.md5DigestAsHex(String.valueOf(taskIdRaw).getBytes());

        // request中加入id
        request.setTaskId(taskId);

        // 发送任务消息
        String msg = new ObjectMapper().writeValueAsString(request);
        clusterWebSocket.sendMessage(nodeId, msg);
        return taskId;
    }

    @Override
    public TaskResult getResult(String taskId) throws JsonProcessingException {
        String msg = clusterWebSocket.getTaskMessage(taskId);
        if (msg == null || msg.isEmpty()) {
            return null;
        }
        return new ObjectMapper().readValue(msg, TaskResult.class);
    }
}
